#include "types/common.h"
#include "modules/buffer_mgr.h"

#ifndef _record_h_
#define _record_h_

enum ConditionType {val_check,attr_check};
enum Operation {eq,gt,lt,ge,le,ne};

struct Condition
{
	ConditionType type;
	Operation op;
	UINT32 lvalue;
	UINT32 rvalue;
};


struct RecordId
{
	UINT32 block_num;
	UINT32 slot_num;
};

struct Record
{
	inline Record() : size(0), data(NULL)
	{
		//debug("\nconstructor 1 NULL");
	}
	inline Record(const Record &r2)
	{
		size = r2.size;
		data = new BYTE[r2.size];
		memcpy(data, r2.data, size);
		id = r2.id;
		//debug("\nconstructor 2 %X", data);		
	}
	
	inline Record & operator = (const Record &r2)
	{
		size = r2.size;
		data = new BYTE[r2.size];
		memcpy(data, r2.data, size);
		id = r2.id;
		//debug("\noperator = %X", data);				
		return *this;
	}
	
	inline Record(int num_attrs) : size(num_attrs * 4)
	{
		data = new BYTE[size];
		//debug("\nconstructor 3 %X", data);				
	};
	
	inline Record(vector<UINT32> values) : size(values.size() * 4)
	{
		data = new BYTE[size];
		UINT32 *attr = (UINT32*) data;
		for(UINT32 i=0; i<values.size(); i++)
		{
			attr[i] = values[i];
		}
		//debug("\nconstructor 4 %X", data);				
	};
	
	inline Record(RecordId rid, int num_attrs, vector<UINT32> values) : id(rid), size(num_attrs * 4)
	{
		data = new BYTE[size];
		UINT32 *attr = (UINT32*) data;
		for(UINT32 i=0; i<values.size(); i++)
		{
			attr[i] = values[i];
		}
		//debug("\nconstructor 5 %X", data);				
	};
	
	inline ~Record()
	{
		//debug("\ndestructor %X", data);			
		if(data != NULL)
			delete [] data;
	}
	
	inline void set_data(BYTE *ptr)
	{
		memcpy(data, ptr, size);
	}
	
	inline BYTE * get_data()
	{
		return data;
	}
	
	inline UINT32 attribute(int index)
	{
		UINT32 *attr = (UINT32 *) data;
		return attr[index];
	}
	
	inline bool check(Condition c)
	{
		UINT32 *attr = (UINT32 *) data;
		if(c.type == attr_check)
		{
			switch(c.op)
			{	
				case eq:
					return attr[c.lvalue] == attr[c.rvalue];
					break;
				case gt:
					return attr[c.lvalue] > attr[c.rvalue];
					break;
				case lt:
					return attr[c.lvalue] < attr[c.rvalue];
					break;
				case ge:
					return attr[c.lvalue] >= attr[c.rvalue];
					break;
				case le:
					return attr[c.lvalue] <= attr[c.rvalue];
					break;
				case ne:
					return attr[c.lvalue] != attr[c.rvalue];
					break;
				default:
					break;
			}
		}
		else
		{
			switch(c.op)
			{
				case eq:
					return attr[c.lvalue] == c.rvalue;
					break;
				case gt:
					return attr[c.lvalue] > c.rvalue;
					break;
				case lt:
					return attr[c.lvalue] < c.rvalue;
					break;
				case ge:
					return attr[c.lvalue] >= c.rvalue;
					break;
				case le:
					return attr[c.lvalue] <= c.rvalue;
					break;
				case ne:
					return attr[c.lvalue] != c.rvalue;
					break;
				default:
					break;
			}
		}
		return false;
	}

	RecordId id;	
private:
	UINT32 size;
	BYTE *data;
};

#endif
